home *** CD-ROM | disk | FTP | other *** search
- /* ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ */
- /* ▌ tc_asm.c ▐ */
- /* ▌ ▐ */
- /* ▌ to compile: tcc -ms -c tc_asm ▐ */
- /* ▌ -ms = Small Model ▐ */
- /* ▌ Change if Desired ▐ */
- /* ▌ (note #define LARGE) ▐ */
- /* ▌ ▐ */
- /* ▌ requires MASM for the inline assembly ▐ */
- /* ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ */
-
- #pragma inline
-
-
- #define LARGE 0 /* 0 for SMALL model */
- /* change to 1 for LARGE model */
-
-
-
- /* ╔══ FUNCTION DECLARATIONS ═══════════════════════╗ */
-
- void fastwrite(int, int, int, char *);
- void getscrn(char far*);
- void dma_ca(int, int, int, int);
- void putscrn(char far*);
- void dma_str(char *, int);
- void scn_attr(int,int,int,int);
- void set_drive(int);
- int vpeek(unsigned , unsigned);
- void vpoke(unsigned, unsigned, unsigned);
-
- /* ╚══ FUNCTION DECLARATIONS ═══════════════════════╝ */
-
-
-
- /* ╔══════════════════════════════════════════════════════════════════════╗ */
- /* ║ Function : fastwrite(); ║ */
- /* ╠══════════════════════════════════════════════════════════════════════╣ */
- /* ║ direct screen write of character and attribute with snow check ║ */
- /* ╠══════════════════════════════════════════════════════════════════════╣ */
- /* ║ Usage : fastwrite(col,row,attr,string) ║ */
- /* ║ ║ */
- /* ║ Returns : nothing ║ */
- /* ╚══════════════════════════════════════════════════════════════════════╝ */
- void fastwrite(int col, int row, int attr, char *st)
- {
- asm mov bx,si /* save SI in BX */
- asm mov ax,40h /* get video mode */
- asm mov es,ax
- asm mov dl,es:[49h] /* DL=Video mode, stored by BIOS */
- asm mov di,row /* DI=Row */
- asm mov cl,4 /* CL=4, CH=0 */
- asm shl di,cl /* DI=Row*32 */
- asm mov ax,di /* store in AX */
- asm shl di,1 /* DI=Row*32 */
- asm shl di,1 /* DI=Row*64 */
- asm add di,ax /* di=row*80 */
- asm add di,col /* Add (Col +1) to di */
- asm shl di,1 /* account for attribute byte */
- #if LARGE
- asm lds si,st /* DS:SI points to String */
- # else
- asm mov si,st /* DS:SI points to String */
- #endif
- asm mov ah,attr /* AH = attribute */
- asm cmp dl,7 /* Mono?? */
- asm je mono
- asm mov dx,0b800h /* base of video buffer */
- asm mov es,dx /* ES = segment for color memory */
- asm mov dx,03dah /* 6845 port address */
-
- getnext:
- asm lodsb /* load next char into al */
- asm or al,al /* test for null character */
- asm jz exit /* exit if it's a null */
- asm mov cx,ax /* store video word in CX */
- asm cli /* no interrupts */
-
- waitnoh:
- asm in al,dx /* get 6845 status */
- asm test al,8 /* Vertical retrace? */
- asm jnz store /* if so, go */
- asm rcr al,1 /* else, wait for end of */
- asm jc waitnoh /* horizontal retrace */
-
- waith:
- asm in al,dx /* get 6845 status again */
- asm rcr al,1 /* wait for horizontal */
- asm jnc waith /* retrace */
-
- store:
- asm mov ax,cx /* move word back to AX.. */
- asm stosw /* and then to screen */
- asm sti /* allow interrupts */
- asm jmp short getnext /* get next character */
-
- mono:
- asm mov dx,0b000h
- asm mov es,dx /* ES = segment for mono memory */
-
- next:
- asm lodsb /* Load next char into AL */
- asm or al,al /* Test for null char */
- asm jz exit /* Exit if it's a null */
- asm stosw /* Move video word into place */
- asm jmp short next /* get next character */
-
- exit:
- asm mov si,bx /* restore SI from BX */
- }
-
-
- /* ╔══════════════════════════════════════════════════════════════════════╗ */
- /* ║ Function : getscrn(); ║ */
- /* ╠══════════════════════════════════════════════════════════════════════╣ */
- /* ║ puts screen to memory buffer using direct screen writes w/snowcheck ║ */
- /* ╠══════════════════════════════════════════════════════════════════════╣ */
- /* ║ Usage : getscrn(buff); ║ */
- /* ║ ║ */
- /* ║ Returns : nothing ║ */
- /* ║ ║ */
- /* ╠══════════════════════════════════════════════════════════════════════╣ */
- /* ║ ex: static char buff[4000]; ║ */
- /* ║ ║ */
- /* ║ getscrn(buff); SAVE SCREEN ║ */
- /* ║ other_stuff(); DO SOME STUFF ║ */
- /* ║ putscrn(buff); RESTORE SCREEN ║ */
- /* ╚══════════════════════════════════════════════════════════════════════╝ */
- void getscrn(buff)
- char far *buff;
- {
- asm push ds
- asm push es
-
- asm mov ah,15
- asm int 10h
- asm mov dx,3BAh
- asm mov si,0
- asm cmp al,7
- asm je movscn
- asm mov dx,3DAh
- asm mov si,8000h
-
- movscn:
- asm mov ax,0B000h
- asm push ds
- asm pop es
- asm mov ds,ax
-
- #if LARGE
- asm les di,buff
- #else
- asm mov di,buff
- #endif
- asm mov cx,80*25
-
- wait_hi:
- asm in al,dx
- asm test al,1
- asm jnz wait_hi
- asm cli
-
- wait_lo:
- asm in al,dx
- asm test al,1
- asm jz wait_lo
- asm movsw
- asm sti
- asm loop wait_hi
-
- asm pop es
- asm pop ds
- }
-
-
- /* ╔══════════════════════════════════════════════════════════════════════╗ */
- /* ║ Function : dma_ca(); ║ */
- /* ╠══════════════════════════════════════════════════════════════════════╣ */
- /* ║ put character and attribute to screen at a column/row using direct ║ */
- /* ║ screen writes w/snowcheck ║ */
- /* ╠══════════════════════════════════════════════════════════════════════╣ */
- /* ║ Usage : dma_ca(col,row,attr,cha); ║ */
- /* ║ ║ */
- /* ║ Returns : nothing ║ */
- /* ╚══════════════════════════════════════════════════════════════════════╝ */
- void dma_ca(col,row,attr,cha)
- int col,row,attr,cha;
- {
- int buff;
- buff = row * 80 + col;
-
- asm push ds
-
-
- asm mov ah,15
- asm int 10h
- asm mov dx,3BAh
- asm mov di,buff
- asm add di,di
- asm cmp al,7
- asm je movmno
- asm mov dx,3DAh
- asm mov ax,0B800h
- asm jmp Video
-
- movmno:
- asm mov ax,0B000h
- asm mov es,ax
- asm mov cx,1
- asm mov al,cha
- asm mov es:[di],al
- asm add di,1
- asm mov al,attr
- asm mov es:[di],al
- asm jmp exit
-
- Video:
- asm mov es,ax
- asm mov cx,1
-
- wait_hi:
- asm in al,dx
- asm test al,1
- asm jnz wait_hi
-
- wait_lo:
- asm in al,dx
- asm test al,1
- asm jz wait_lo
- asm mov al,cha
- asm mov es:[di],al
-
- asm add di,1
-
- wait_h2:
- asm in al,dx
- asm test al,1
- asm jnz wait_h2
-
- wait_l2:
- asm in al,dx
- asm test al,1
- asm jz wait_l2
- asm mov al,attr
- asm mov es:[di],al
-
- exit:
- asm pop ds
- }
-
-
- /* ╔══════════════════════════════════════════════════════════════════════╗ */
- /* ║ Function : putscrn(); ║ */
- /* ╠══════════════════════════════════════════════════════════════════════╣ */
- /* ║ puts memory buffer to screen using direct screen writes w/snowcheck ║ */
- /* ╠══════════════════════════════════════════════════════════════════════╣ */
- /* ║ Usage : putscrn(buff); ║ */
- /* ║ ║ */
- /* ║ Returns : nothing ║ */
- /* ╠══════════════════════════════════════════════════════════════════════╣ */
- /* ║ ex: static char buff[4000]; ║ */
- /* ║ ║ */
- /* ║ getscrn(buff); SAVE SCREEN ║ */
- /* ║ other_stuff(); DO SOME STUFF ║ */
- /* ║ putscrn(buff); RESTORE SCREEN ║ */
- /* ╚══════════════════════════════════════════════════════════════════════╝ */
- void putscrn(buff)
- char far *buff;
- {
- asm mov ah,15
- asm int 10h
- asm mov dx,3BAh
- asm mov di,0
- asm cmp al,7
- asm je movscn
- asm mov dx,3DAh
- asm mov di,8000h
- movscn:
- asm mov ax,0B000h
- asm mov es,ax
-
- #if LARGE
- asm push ds
- asm lds si,buff
- #else
- asm mov si,buff
- #endif
- asm mov cx,80*25
-
- wait_hi:
- asm in al,dx
- asm test al,1
- asm jnz wait_hi
- wait_lo:
- asm in al,dx
- asm test al,1
- asm jz wait_lo
- asm movsw
-
- asm loop wait_hi
-
- #if LARGE
- asm pop ds
- #endif
- }
-
-
- /* ╔══════════════════════════════════════════════════════════════════════╗ */
- /* ║ Function : dma_str(); ║ */
- /* ╠══════════════════════════════════════════════════════════════════════╣ */
- /* ║ writes string and attribute direct to screen w/snowcheck ║ */
- /* ╠══════════════════════════════════════════════════════════════════════╣ */
- /* ║ Usage : dma_str(string,attr); ║ */
- /* ║ ║ */
- /* ║ Returns : nothing ║ */
- /* ╠══════════════════════════════════════════════════════════════════════╣ */
- /* ║ requires: fastwrite(); ║ */
- /* ╚══════════════════════════════════════════════════════════════════════╝ */
- void dma_str(char *st, int attr)
- {
- int row,col,x1;
- row = where_y();
- col = where_x();
- x1 = col + strlen(st);
- fastwrite(col,row,attr,st);
- if(x1 > 79) {
- col = x1 - 80;
- row++;
- }
- else
- col = x1;
- if(row > 24) {
- scroll(0,0,79,24,1,0);
- row = 24;
- }
- gotoxy(col,row);
- }
-
-
- /* ╔══════════════════════════════════════════════════════════════════════╗ */
- /* ║ Function : scn_attr(); ║ */
- /* ╠══════════════════════════════════════════════════════════════════════╣ */
- /* ║ writes attributes only direct to screen with CGA snowcheck ║ */
- /* ╠══════════════════════════════════════════════════════════════════════╣ */
- /* ║ Usage : scn_attr(attr,col,row,len); ║ */
- /* ║ ║ */
- /* ║ Returns : nothing ║ */
- /* ╚══════════════════════════════════════════════════════════════════════╝ */
- void scn_attr(attr,col,row,len)
- int attr,col,row,len;
- {
- int buff;
- buff = row * 80 + col;
-
- asm push ds
-
-
- asm mov ah,15
- asm int 10h
- asm mov dx,3BAh
- asm mov di,buff
- asm add di,di
- asm cmp al,7
- asm je movmno
- asm mov dx,3DAh
- asm mov ax,0B800h
- asm jmp Video
-
- movmno:
- asm mov ax,0B000h
- Video:
- asm add di,1
- asm mov es,ax
- asm mov cx,len
-
- wait_hi:
- asm in al,dx
- asm test al,1
- asm jnz wait_hi
-
- wait_lo:
- asm in al,dx
- asm test al,1
- asm jz wait_lo
- asm mov ah,attr
- asm mov es:[di],ah
- asm add di,2
- asm loop wait_hi
-
- asm pop ds
- }
-
-
- /* ╔══════════════════════════════════════════════════════════════════════╗ */
- /* ║ Function : set_drive(); ║ */
- /* ╠══════════════════════════════════════════════════════════════════════╣ */
- /* ║ see if drive is available, and if so, change to it ║ */
- /* ╠══════════════════════════════════════════════════════════════════════╣ */
- /* ║ Usage : set_drive(num); ║ */
- /* ║ num -> 0=A, 1=B, 2=C, 3=D, etc. ║ */
- /* ║ ║ */
- /* ║ Returns : nothing ║ */
- /* ╚══════════════════════════════════════════════════════════════════════╝ */
-
- void set_drive(drv_num)
- int drv_num;
- {
- int new_drv,cur_drv;
- asm mov ah,19h /* get current drive */
- asm int 21h
- asm mov cur_drv,al /* save it to cur_drv */
- asm mov ah,0eh /* select disk drive */
- asm mov dl,drv_num
- asm int 21h
- asm mov ah,19h /* get the drive */
- asm int 21h
- asm cmp al,drv_num /* compare it */
- asm je n_drive
- asm mov al,cur_drv /* not there so make */
- asm mov drv_num,al /* drv_num the cur_drv */
- n_drive:
- asm mov ah,0eh
- asm mov dl,drv_num /* set to drv_num */
- asm int 21h
- }
-
-
- /* ╔══════════════════════════════════════════════════════════════════════╗ */
- /* ║ Function : vpeek(); ║ */
- /* ╠══════════════════════════════════════════════════════════════════════╣ */
- /* ║ read a character and attribute int video ram with CGA snowcheck ║ */
- /* ╠══════════════════════════════════════════════════════════════════════╣ */
- /* ║ Usage : vpeek(vid_seg,offset); ║ */
- /* ║ ║ */
- /* ║ Returns : character at vid_seg,offset ║ */
- /* ╚══════════════════════════════════════════════════════════════════════╝ */
- int vpeek(unsigned vseg, unsigned adr)
- {
- int ch, at;
-
- if (vseg == 45056) /* monochrome mode */
- return peek(vseg, adr);
- asm push ds;
- _DX = 986; /* video status port */
- _DS = vseg; /* video segment address */
- _SI = adr; /* video character offset */
- asm cld;
- /* -------- wait for video retrace to start -------- */
- do
- asm in al,dx;
- while (_AL & 1);
- /* -------- wait for video retrace to stop -------- */
- do
- asm in al,dx;
- while (!(_AL & 1));
- asm lodsb; /* get the character */
- _BL = _AL;
- /* -------- wait for video retrace to start -------- */
- do
- asm in al,dx;
- while (_AL & 1);
- /* -------- wait for video retrace to stop -------- */
- do
- asm in al,dx;
- while (!(_AL & 1));
- asm lodsb; /* get the attribute */
- _BH = _AL;
- _AX = _BX;
- asm pop ds;
- return _AX;
- }
-
-
- /* ╔══════════════════════════════════════════════════════════════════════╗ */
- /* ║ Function : vpoke(); ║ */
- /* ╠══════════════════════════════════════════════════════════════════════╣ */
- /* ║ insert a character and attribute int video ram with CGA snowcheck ║ */
- /* ╠══════════════════════════════════════════════════════════════════════╣ */
- /* ║ Usage : vpoke(vid_seg,offset,chr); ║ */
- /* ║ ║ */
- /* ║ Returns : nothing ║ */
- /* ╚══════════════════════════════════════════════════════════════════════╝ */
- void vpoke(unsigned vseg, unsigned adr, unsigned chr)
- {
- if (vseg == 45056) /* monochrome mode */
- poke(vseg, adr, chr);
- else {
- _DI = adr; /* offset of video character */
- _ES = vseg; /* video segment */
- asm cld;
- _BX = chr; /* the attribute and character */
- _DX = 986; /* video status port */
- /* -------- wait for video retrace to start -------- */
- do
- asm in al,dx;
- while (_AL & 1);
- /* -------- wait for video retrace to stop -------- */
- do
- asm in al,dx;
- while (!(_AL & 1));
- _AL = _BL;
- asm stosb; /* store character */
- /* -------- wait for video retrace to start -------- */
- do
- asm in al,dx;
- while (_AL & 1);
- /* -------- wait for video retrace to stop -------- */
- do
- asm in al,dx;
- while (!(_AL & 1));
- _AL = _BH;
- asm stosb; /* store attribute */
- }
- }
-
-
-